/*
 *    Copyright (c) 2018-2025, nart All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution.
 * Neither the name of the pig4cloud.com developer nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 * Author: nart
 */
package com.nai365.nart.order.service.impl;

import cn.hutool.core.lang.Console;
import cn.hutool.core.lang.TypeReference;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.nai365.nart.common.core.constant.OrderConstant;
import com.nai365.nart.common.core.constant.SecurityConstants;
import com.nai365.nart.common.core.to.mq.SeckillOrderTo;
import com.nai365.nart.common.core.util.R;
import com.nai365.nart.common.core.vo.SkuInfoVo;
import com.nai365.nart.common.security.service.NartUser;
import com.nai365.nart.common.security.util.SecurityUtils;
import com.nai365.nart.member.feign.RemoteMemberService;
import com.nai365.nart.order.entity.Order;
import com.nai365.nart.order.entity.OrderItem;
import com.nai365.nart.order.entity.PaymentInfo;
import com.nai365.nart.order.feign.MemberFeignService;
import com.nai365.nart.order.feign.ProductFeignService;
import com.nai365.nart.order.feign.WmsFeignService;
import com.nai365.nart.order.mapper.OrderMapper;
import com.nai365.nart.order.service.OrderService;
import com.nai365.nart.order.service.PaymentInfoService;
import com.nai365.nart.order.to.OrderCreateTO;
import com.nai365.nart.common.core.to.OrderTO;
import com.nai365.nart.order.to.SpuInfoTO;
import com.nai365.nart.order.to.WareSkuLockTO;
import com.nai365.nart.order.utils.TokenUtil;
import com.nai365.nart.order.vo.*;
import com.nai365.nart.search.api.feign.SearchFeignService;
import com.nai365.nart.seckill.api.feign.SeckillFeignService;
import lombok.AllArgsConstructor;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAdjusters;
import java.util.*;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.stream.Collectors;

import static com.nai365.nart.common.core.constant.SecurityConstants.FROM_IN;

/**
 * 订单
 *
 * @author baogs
 * @date 2022-07-01 14:19:39
 */
@Service
@AllArgsConstructor
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements OrderService {

	// 提交订单共享提交数据
//	private ThreadLocal<OrderSubmitVO> confirmVoThreadLocal = new ThreadLocal<>();

	MemberFeignService memberFeignService;
//	@Autowired
//	CartFeignService cartFeignService;
	WmsFeignService wmsFeignService;
	SearchFeignService searchFeignService;
	ProductFeignService productFeignService;
	OrderItemServiceImpl orderItemService;
	PaymentInfoService paymentInfoService;

	SeckillFeignService seckillFeignService;

	@Autowired
	ThreadPoolExecutor executor;
	RabbitTemplate rabbitTemplate;
	TokenUtil tokenUtil;

	RemoteMemberService remoteMemberService;




	/**
	 * 获取订单详情
	 */
	@Override
	public Order getOrderByOrderSn(String orderSn) {
		return getOne(new QueryWrapper<Order>().eq("order_sn", orderSn));
	}

	/**
	 * 获取结算页（confirm.html）VO数据
	 */
	@Override
	public OrderConfirmVO OrderConfirmVO() throws Exception {
		OrderConfirmVO result = new OrderConfirmVO();
		// 获取当前用户
//		MemberResponseVO member = LoginUserInterceptor.loginUser.get();
		NartUser member = SecurityUtils.getUser();

		// 获取当前线程上下文环境器
		ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
//		CompletableFuture<Void> addressFuture = CompletableFuture.runAsync(() -> {
//			// 1.查询封装当前用户收货列表
//			// 同步上下文环境器，解决异步无法从ThreadLocal获取RequestAttributes
//			RequestContextHolder.setRequestAttributes(requestAttributes);
//			List<MemberAddressVO> address = memberFeignService.getAddress(member.getId());
//			result.setMemberAddressVos(address);
//		}, executor);

//		CompletableFuture<Void> cartFuture = CompletableFuture.runAsync(() -> {
//			// 2.查询购物车所有选中的商品
//			// 同步上下文环境器，解决异步无法从ThreadLocal获取RequestAttributes
//			RequestContextHolder.setRequestAttributes(requestAttributes);
//			// 请求头应该放入GULIMALLSESSION（feign请求会根据requestInterceptors构建请求头）
//			List<OrderItemVO> items = cartFeignService.getCurrentCartItems();
//			result.setItems(items);
//		}, executor).thenRunAsync(() -> {

//		CompletableFuture<Void> wareFuture = CompletableFuture.runAsync(() -> {
//			// 3.批量查询库存（有货/无货）
//			List<Long> skuIds = result.getItems().stream().map(item -> item.getSkuId()).collect(Collectors.toList());
//			R skuHasStock = wmsFeignService.getSkuHasStock(skuIds);
//			List<SkuHasStockTO> skuHasStocks = JSONUtil.toList(skuHasStock.getData().toString(), SkuHasStockTO.class);
//			Map<Long, Boolean> stocks = skuHasStocks.stream().collect(Collectors.toMap(key -> key.getSkuId(), val -> val.getHasStock()));
//			result.setStocks(stocks);
//		}, executor);
//
//



		// 4.查询用户积分
//		Integer integration = member.getIntegration();// 积分
//		result.setIntegration(integration);

		// 5.金额数据自动计算

		// 6.防重令牌
		String token = tokenUtil.createToken();
		result.setUniqueToken(token);

		// 阻塞等待所有异步任务返回
//		CompletableFuture.allOf(wareFuture).get();

		return result;
	}

	/**
	 * 创建订单
	 * GlobalTransactional：seata分布式事务，不适合高并发场景（默认基于AT实现）
	 *
	 * @param: vo 收货地址、发票信息、使用的优惠券、备注、应付总额、令牌
	 */
	//@GlobalTransactional
	@Transactional
	@Override
	public SubmitOrderResponseVO submitOrder(OrderSubmitVO orderSubmitVO) throws Exception {
		SubmitOrderResponseVO result = new SubmitOrderResponseVO();// 返回值

		Long skuId = orderSubmitVO.getSkuId();

		SkuInfoVo skuInfo = null;
		if(skuId == 1548907444944642056L || skuId == 1548907444944642057L ){
			R productSkuInfo = productFeignService.getInfo(orderSubmitVO.getSkuId(), SecurityConstants.FROM_IN);
			 skuInfo = (SkuInfoVo) productSkuInfo.getData(JSONUtil.toJsonStr(productSkuInfo.getData()), new TypeReference<SkuInfoVo>() {
			});

		} else {
			R skuInfoData = searchFeignService.getSkuInfo(skuId,1,SecurityConstants.FROM_IN);
			if (skuInfoData.getCode() == 0) {
				JSONObject entries = JSONUtil.parseObj(skuInfoData.getData());
				Object product = entries.get("product");
				if (product != null) {
					List<SkuInfoVo> skuInfoVos = JSONUtil.toList(product.toString(), SkuInfoVo.class);
					skuInfo = skuInfoVos.get(0);
				}
			}
		}
		Long userId = SecurityUtils.getUser().getId();

		if (userId.equals(skuInfo.getOwnerId())){
			throw new RuntimeException("不能购买自己的藏品");
		}

//		R productSkuInfo = productFeignService.getInfo(orderSubmitVO.getSkuId(), SecurityConstants.FROM_IN);
//		SkuInfoVo skuInfo = (SkuInfoVo) productSkuInfo.getData(JSONUtil.toJsonStr(productSkuInfo.getData()), new TypeReference<SkuInfoVo>() {
//		});


		OrderItemVO cartItemVo = new OrderItemVO();
		cartItemVo.setSkuId(skuInfo.getSkuId());
		cartItemVo.setTitle(skuInfo.getSkuName());
		cartItemVo.setSkuCode(skuInfo.getSkuCode());
		cartItemVo.setToken(skuInfo.getToken());
		cartItemVo.setCount(1);
		if (skuId == 1548907444944642056L || skuId == 1548907444944642057L) {
			cartItemVo.setPrice(orderSubmitVO.getPayPrice());
		} else {
			cartItemVo.setPrice(skuInfo.getPrice());
		}
		cartItemVo.setImage(skuInfo.getSkuDefaultImg());


		// 创建订单线程共享提交数据
//		confirmVoThreadLocal.set(orderSubmitVO);
		// 1.生成订单实体对象（订单 + 订单项）
//		OrderCreateTO order = createOrder();
		OrderCreateTO order = createOrder(cartItemVo);
		order.getOrder().setOrderType(orderSubmitVO.getOrderType());
		order.getOrder().setDataId(skuId);
		order.getOrder().setOwnId(skuInfo.getOwnerId());
//		 2.验价应付金额（允许0.01误差，前后端计算不一致）
		if (Math.abs(orderSubmitVO.getPayPrice().subtract(order.getPayPrice()).doubleValue()) >= 0.01) {
			// 验价不通过
			throw new RuntimeException("订单商品价格发生变化，请确认后再次提交");
		}
		// 验价成功
		// 3.保存订单
		saveOrder(order);
		// 4.库存锁定（wms_ware_sku）
		// 封装待锁定商品项TO
		WareSkuLockTO lockTO = new WareSkuLockTO();
		lockTO.setOrderSn(order.getOrder().getOrderSn());
		List<OrderItemVO> locks = order.getOrderItems().stream().map((item) -> {
			OrderItemVO lock = new OrderItemVO();
			lock.setSkuId(item.getSkuId());
			lock.setCount(item.getSkuQuantity());
			lock.setTitle(item.getSkuName());
			return lock;
		}).collect(Collectors.toList());
		lockTO.setLocks(locks);// 待锁定订单项
		R response = wmsFeignService.orderLockStock(lockTO,SecurityConstants.FROM_IN);
		if (response.getCode() == 0) {
			// 锁定成功
			// TODO 5.远程扣减积分
			// 封装响应数据返回
			result.setOrder(order.getOrder());
			//System.out.println(10 / 0); // 模拟订单回滚，库存不会滚
			// 6.发送创建订单到延时队列
			rabbitTemplate.convertAndSend("order-event-exchange", "order.create.order", order.getOrder());
			return result;
		} else {
			// 锁定失败
			throw new RuntimeException("锁定库存失败");
		}
	}

	/**
	 * 封装订单实体类对象
	 * 订单 + 订单项
	 */
	private OrderCreateTO createOrder(OrderItemVO orderItemVO) throws Exception {
		OrderCreateTO result = new OrderCreateTO();// 订单
		// 1.生成订单号
		String orderSn = IdWorker.getIdStr();
		// 2.生成订单实体对象
		Order Order = buildOrder(orderSn);
		// 3.生成订单项实体对象
//		List<OrderItem> orderItemEntities = buildOrderItems(orderSn);
		List<OrderItem> orderItemEntities = new ArrayList<OrderItem>();
		OrderItem orderItem = buildOrderItem(orderSn, orderItemVO);
		orderItemEntities.add(orderItem);

		// 4.汇总封装（封装订单价格[订单项价格之和]、封装订单积分、成长值[订单项积分、成长值之和]）
		summaryFillOrder(Order, orderItemEntities);

		// 5.封装TO返回
		result.setOrder(Order);
		result.setOrderItems(orderItemEntities);
//		result.setFare(Order.getFreightAmount());
		result.setPayPrice(Order.getPayAmount());// 设置应付金额
		return result;
	}

	/**
	 * 生成订单实体对象
	 *
	 * @param orderSn 订单号
	 */
	private Order buildOrder(String orderSn) {
		Order Order = new Order();// 订单实体类
		// 1.封装会员ID
//		MemberResponseVO member = LoginUserInterceptor.loginUser.get();// 拦截器获取登录信息
		NartUser user = SecurityUtils.getUser();
		Order.setMemberId(user.getId());
		// 2.封装订单号
		Order.setOrderSn(orderSn);
		// 3.封装运费
//		OrderSubmitVO orderSubmitVO = confirmVoThreadLocal.get();
//		R fare = wmsFeignService.getFare(orderSubmitVO.getAddrId());// 获取地址
//		FareVO fareVO = fare.getData(new TypeReference<FareVO>() {
//		});
//		Order.setFreightAmount(fareVO.getFare());
		// 4.封装收货地址信息
//		Order.setReceiverName(fareVO.getAddress().getName());// 收货人名字
//		Order.setReceiverPhone(fareVO.getAddress().getPhone());// 收货人电话
//		Order.setReceiverProvince(fareVO.getAddress().getProvince());// 省
//		Order.setReceiverCity(fareVO.getAddress().getCity());// 市
//		Order.setReceiverRegion(fareVO.getAddress().getRegion());// 区
//		Order.setReceiverDetailAddress(fareVO.getAddress().getDetailAddress());// 详细地址
//		Order.setReceiverPostCode(fareVO.getAddress().getPostCode());// 收货人邮编
		// 5.封装订单状态信息
		Order.setStatus(OrderConstant.OrderStatusEnum.CREATE_NEW.getCode());
		// 6.设置自动确认时间
		Order.setAutoConfirmDay(OrderConstant.autoConfirmDay);// 7天
		// 7.设置未删除状态
		Order.setDeleteStatus(0);
		// 8.设置时间
		LocalDateTime now = LocalDateTime.now();
		Order.setCreateTime(now);
		Order.setModifyTime(now);
		return Order;
	}


	/**
	 * 生成单个订单项实体对象
	 */
	private OrderItem buildOrderItem(String orderSn, OrderItemVO cartItem) {
		OrderItem itemEntity = new OrderItem();
		// 1.封装订单号
		itemEntity.setOrderSn(orderSn);
		// 2.封装SPU信息
		R spuInfo = productFeignService.getSpuInfoBySkuId(cartItem.getSkuId(),FROM_IN);// 查询SPU信息
//		SpuInfoTO spuInfoTO = spuInfo.getData(new TypeReference<SpuInfoTO>() {
//		});
		SpuInfoTO spuInfoTO = JSONUtil.toBean(JSONUtil.toJsonStr(spuInfo.getData()), SpuInfoTO.class);
		itemEntity.setSpuId(spuInfoTO.getId());
		itemEntity.setSpuName(spuInfoTO.getSpuName());
		itemEntity.setSpuBrand(spuInfoTO.getSpuName());
		itemEntity.setCategoryId(spuInfoTO.getCatalogId());
		// 3.封装SKU信息
		itemEntity.setSkuId(cartItem.getSkuId());
		itemEntity.setSkuName(cartItem.getTitle());
		itemEntity.setSkuPic(cartItem.getImage());// 商品sku图片
		itemEntity.setSkuPrice(cartItem.getPrice());// 这个是最新价格，购物车模块查询数据库得到
		itemEntity.setSkuQuantity(cartItem.getCount());// 当前商品数量
		itemEntity.setSkuCode(cartItem.getSkuCode());
		itemEntity.setToken(cartItem.getToken());
		// 4.优惠信息【不做】

		// 5.积分信息
		int num = cartItem.getPrice().multiply(new BigDecimal(cartItem.getCount())).intValue();// 分值=单价*数量
		itemEntity.setGiftGrowth(num);// 成长值
		itemEntity.setGiftIntegration(num);// 积分

		// 6.价格信息
		itemEntity.setPromotionAmount(BigDecimal.ZERO);// 促销金额
		itemEntity.setCouponAmount(BigDecimal.ZERO);// 优惠券金额
		itemEntity.setIntegrationAmount(BigDecimal.ZERO);// 积分优惠金额
		BigDecimal realAmount = itemEntity.getSkuPrice().multiply(new BigDecimal(itemEntity.getSkuQuantity()))
				.subtract(itemEntity.getPromotionAmount())
				.subtract(itemEntity.getCouponAmount())
				.subtract(itemEntity.getIntegrationAmount());
		itemEntity.setRealAmount(realAmount);// 实际金额，减去所有优惠金额
		return itemEntity;
	}

	/**
	 * 汇总封装订单
	 * 1.计算订单总金额
	 * 2.汇总积分、成长值
	 * 3.汇总应付总额 = 订单总金额 + 运费
	 *
	 * @param Order       订单
	 * @param orderItemEntities 订单项
	 */
	private void summaryFillOrder(Order Order, List<OrderItem> orderItemEntities) {
		// 1.订单总额、促销总金额、优惠券总金额、积分优惠总金额
		BigDecimal total = new BigDecimal(0);
		BigDecimal coupon = new BigDecimal(0);
		BigDecimal promotion = new BigDecimal(0);
		BigDecimal integration = new BigDecimal(0);
		// 2.积分、成长值
		Integer giftIntegration = 0;
		Integer giftGrowth = 0;
		for (OrderItem itemEntity : orderItemEntities) {
			total = total.add(itemEntity.getRealAmount());// 订单总额
			coupon = coupon.add(itemEntity.getCouponAmount());// 促销总金额
			promotion = promotion.add(itemEntity.getPromotionAmount());// 优惠券总金额
			integration = integration.add(itemEntity.getIntegrationAmount());// 积分优惠总金额
			giftIntegration = giftIntegration + itemEntity.getGiftIntegration();// 积分
			giftGrowth = giftGrowth + itemEntity.getGiftGrowth();// 成长值
		}
		Order.setTotalAmount(total);
		Order.setCouponAmount(coupon);
		Order.setPromotionAmount(promotion);
		Order.setIntegrationAmount(integration);
		Order.setIntegration(giftIntegration);// 积分
		Order.setGrowth(giftGrowth);// 成长值

		// 3.应付总额
		Order.setPayAmount(Order.getTotalAmount());// 订单总额 +　运费
	}

	/**
	 * 保存订单
	 * 将封装生成的订单对象 + 订单项对象持久化到DB
	 *
	 * @param order
	 */
	private void saveOrder(OrderCreateTO order) {
		// 1.持久化订单对象
		Order Order = order.getOrder();
		save(Order);

		// 2.持久化订单项对象
		List<OrderItem> itemEntities = order.getOrderItems();
		itemEntities.get(0).setOrderId(Order.getId());
		orderItemService.saveBatch(itemEntities);
	}

	/**
	 * 关闭订单
	 */
	@Override
	public void closeOrder(Order order) {
		Order _order = getById(order.getId());
		if (OrderConstant.OrderStatusEnum.CREATE_NEW.getCode().equals(_order.getStatus())) {
			// 待付款状态允许关单
			Order temp = new Order();
			temp.setId(order.getId());
			temp.setStatus(OrderConstant.OrderStatusEnum.CANCLED.getCode());
			updateById(temp);
			Integer orderType = _order.getOrderType();
			if (orderType !=null && orderType < 4){
				OrderItem orderItem = orderItemService.findOrderItemByOrderId(_order.getId());
				try {
					seckillFeignService.closeOrderStockHandler(orderItem.getSkuId(), FROM_IN);
				} catch (Exception e) {
					e.printStackTrace();
				}

			} else {
				try {
					// 发送消息给MQ
					OrderTO orderTO = new OrderTO();
					BeanUtils.copyProperties(_order, orderTO);
					//TODO 持久化消息到mq_message表中，并设置消息状态为3-已抵达（保存日志记录）
					rabbitTemplate.convertAndSend("order-event-exchange", "order.release.other", orderTO);
				} catch (Exception e) {
					// TODO 消息为抵达Broker，修改mq_message消息状态为2-错误抵达
				}
			}
		}
	}

	/**
	 * 获取订单支付的详细信息
	 *
	 * @param orderSn 订单号
	 */
	@Override
	public PayVO getOrderPay(String orderSn) {
		// 查询订单
		Order order = this.getOrderByOrderSn(orderSn);
		// 查询所有订单项
		OrderItem item = orderItemService.list(new QueryWrapper<OrderItem>()
				.eq("order_sn", orderSn)).get(0);
		PayVO result = new PayVO();
		BigDecimal amount = order.getPayAmount().setScale(2, BigDecimal.ROUND_UP);// 总金额
		result.setTotal_amount(amount.toString());
		result.setOut_trade_no(orderSn);
		result.setSubject(item.getSkuName());
		result.setBody(item.getSkuAttrsVals());
		return result;
	}

	/**
	 * 处理支付回调
	 *
	 * @param targetOrderStatus 目标状态
	 */
	@Override
	public void handlePayResult(Integer targetOrderStatus, Integer payCode, PaymentInfo paymentInfo) {
		// 保存交易流水信息
		paymentInfoService.save(paymentInfo);

		// 修改订单状态
		if (OrderConstant.OrderStatusEnum.PAYED.getCode().equals(targetOrderStatus)) {
			// 支付成功状态
			String orderSn = paymentInfo.getOrderSn();
			this.updateOrderStatus(orderSn, targetOrderStatus, payCode);
		}
	}

	/**
	 * 查询当前用户所有订单数据
	 *
	 * @param order
	 * @return
	 */
	@Override
	public IPage queryPageWithItem(Page page, Order order,Integer type) {

		LambdaQueryWrapper<Order> queryWrapper = Wrappers.<Order>lambdaQuery(order);
		Long userId = SecurityUtils.getUser().getId();
		if (type == null || type == 0) {
			queryWrapper.eq(Order::getMemberId, userId)
					.notIn(Order::getOrderType,4,5);
		} else if (type == 1) {
			queryWrapper.eq(Order::getOwnId, userId)
					.notIn(Order::getOrderType,4,5);
		} else if (type == 2){
			queryWrapper.eq(Order::getOwnId, userId).or().eq(Order::getMemberId, userId)
					.orderByDesc(Order::getModifyTime)
					.notIn(Order::getOrderType,4,5);
		}

		IPage<Order> page1 = page(page, queryWrapper);

		List<Order> records = page1.getRecords();
		List<Long> memberIds = records.parallelStream().map(item -> item.getMemberId()).collect(Collectors.toList());
		List<Long> ownerIds = records.parallelStream().map(item -> item.getOwnId()).collect(Collectors.toList());
		 memberIds.addAll(ownerIds);
		memberIds = memberIds.parallelStream().distinct().collect(Collectors.toList());
		final Map<String, Map> infos = new HashMap<>();
		R headerAndNickname = remoteMemberService.findHeaderAndNickname(memberIds, FROM_IN);
		if (headerAndNickname.getCode() == 0){

			Map<String, Map> infos1 = (Map<String, Map>) headerAndNickname.getData();
			infos.putAll(infos1);

		}


		//遍历所有订单集合
		List<Order> OrderList = records.stream().map(item -> {
			//根据订单号查询订单项里的数据
			item.setMemberInfo(infos.get(item.getMemberId()+ ""));
			item.setOwnerInfo(infos.get(item.getOwnId()+ ""));
			List<OrderItem> orderItemEntities = orderItemService.list(Wrappers.<OrderItem>lambdaQuery()
					.eq(OrderItem::getOrderSn, item.getOrderSn()));
			item.setOrderItemEntityList(orderItemEntities);
			Long memberId = item.getMemberId();
			if (memberId.equals(userId) ) {
				item.setType(0);
			} else {
				item.setType(1);
			}

			return item;
		}).collect(Collectors.toList());
		page1.setRecords(OrderList);

		return page1;
	}

	/**
	 * 修改订单状态
	 *
	 * @param orderSn
	 * @param code
	 */
	@Override
	public void updateOrderStatus(String orderSn, Integer code, Integer payType) {
		this.update(Wrappers.<Order>lambdaUpdate()
				.set(Order::getModifyTime,LocalDateTime.now())
				.set(Order::getPaymentTime ,LocalDateTime.now())
				.set(Order::getStatus,code).eq(Order::getOrderSn ,orderSn));
	}
	/**
	 * 创建秒杀订单
	 * @param order 秒杀订单信息
	 */
	@Override
	public void createSeckillOrder(SeckillOrderTo order) {
		// 1.创建订单
		Order Order = new Order();
		Order.setOrderSn(order.getOrderSn());
		Order.setMemberId(order.getMemberId());
		Order.setCreateTime(LocalDateTime.now());
		BigDecimal totalPrice = order.getSeckillPrice().multiply(BigDecimal.valueOf(order.getNum()));// 应付总额
		Order.setTotalAmount(totalPrice);// 订单总额
		Order.setPayAmount(totalPrice);// 应付总额
		Order.setStatus(OrderConstant.OrderStatusEnum.CREATE_NEW.getCode());
		Order.setOrderType(order.getOrderType());
		Order.setDataId(order.getDataId());
		// 保存订单
		this.save(Order);

		// 2.创建订单项信息
		OrderItem orderItem = new OrderItem();
		orderItem.setOrderSn(order.getOrderSn());
		orderItem.setRealAmount(totalPrice);
		orderItem.setSkuQuantity(order.getNum());

		// 保存商品的spu信息
		R r = productFeignService.getSpuInfoBySkuId(order.getSkuId(), SecurityConstants.FROM_IN);
		SpuInfoTO spuInfo = JSONUtil.toBean(JSONUtil.toJsonStr(r.getData()), SpuInfoTO.class);
		orderItem.setSpuId(spuInfo.getId());
		orderItem.setOrderId(Order.getId());
		orderItem.setSpuName(spuInfo.getSpuName());
		orderItem.setSpuBrand(spuInfo.getBrandName());
		orderItem.setCategoryId(spuInfo.getCatalogId());
		orderItem.setSkuId(order.getSkuId());
		orderItem.setSkuName(order.getSkuName());
		orderItem.setSkuPrice(order.getSeckillPrice());
		orderItem.setSpuPic(spuInfo.getChainUrl());
		orderItem.setCatalogName(spuInfo.getCatalogName());
		orderItem.setSpuNameEn(spuInfo.getSpuNameEn());
		orderItem.setSkuCode(spuInfo.getSkuCode());
		orderItem.setToken(spuInfo.getToken());
		// 保存订单项数据
		orderItemService.save(orderItem);
		rabbitTemplate.convertAndSend("order-event-exchange", "order.create.order", Order);
	}


	@Override
	public void completeOrder(Order order) {
		//完成订单之前先查询一下数据库，判断此订单状态是否已支付
		try {
			Order orderInfo = this.getOne(Wrappers.<Order>lambdaQuery().
					eq(Order::getId, order.getId()));
			Integer status = orderInfo.getStatus();
			if (status.equals(OrderConstant.OrderStatusEnum.SENDED.getCode())) {
				//付款状态进行关单
				Order orderUpdate = new Order();
				orderUpdate.setId(orderInfo.getId());
				orderUpdate.setStatus(OrderConstant.OrderStatusEnum.RECIEVED.getCode());
				this.updateById(orderUpdate);

				//更新收入明细改为已结算
//				memberFeignService.updateByOrderSnInner(orderInfo.getOrderSn(),1, SecurityConstants.FROM_IN);

			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}



	/**
	 * 查询今日和全部订单金额
	 *
	 * @param rank rank
	 * @return R
	 */
	@Override
	public R getAllMoney(Integer rank) {
		//得到当前时间:day
		LocalDateTime time = LocalDateTime.now();
		DateTimeFormatter dtf2 = DateTimeFormatter.ofPattern("yyyy-MM-dd");
		String strDate = dtf2.format(time);
		List<Order> list = this.list();
		List<Order> collect = list.stream()
				.filter(e -> dtf2.format(e.getCreateTime()).equals(strDate))
				.collect(Collectors.toList());
		//获取今日0时0分
		LocalDateTime today_start = LocalDateTime.of(LocalDate.now(), LocalTime.MIN);
		//获取这个月的第一天0时0分
		LocalDateTime firstday = today_start.with(TemporalAdjusters.firstDayOfMonth());
		//获取这个月到今天有几天
		int daysNum=(int)(time.toLocalDate().toEpochDay()-firstday.toLocalDate().toEpochDay())+2;
		//查询今天到一号的数据
		List<Order> ordersList = this.list(Wrappers.<Order>lambdaQuery()
				.between(Order::getCreateTime, firstday, time));
		List<BigDecimal> members = Arrays.asList(new BigDecimal[daysNum]);
		switch (rank) {

			//今日交易额
			case 5:
				BigDecimal todayAmount = BigDecimal.valueOf(0);
				for (Order order : collect) {
					todayAmount = todayAmount.add(order.getTotalAmount());
				}
				return R.ok(todayAmount,"5");
				//总交易额
			case 6:
				BigDecimal allAmount = BigDecimal.valueOf(0);
				for (Order order : list) {
					allAmount = allAmount.add(order.getTotalAmount());
				}
				return R.ok(allAmount,"6");
				//月交易额
			case 9:
				//用正则匹配每天对应的集合
				for (int i = 0; i < daysNum; i++) {
					members.set(i, BigDecimal.ZERO);
					//将list所有数据按天进行分组
					Map<String, List<Order>> orderCollect = ordersList.stream()
							.collect(Collectors.groupingBy(item -> dtf2.format(item.getCreateTime())));
					for (String s : orderCollect.keySet()) {
						if(Integer.parseInt(s.substring(s.length() - 2))==i){
							List<Order> orders = orderCollect.get(s);
							BigDecimal bigDecimal = BigDecimal.ZERO;
							for (Order order : orders) {
								bigDecimal = bigDecimal.add(order.getTotalAmount());
							}
							members.set(i, bigDecimal);
						}
					}
				}
				return R.ok(members,"9");
		}
		return null;
	}

	@Override
	public void updateOrderStatusByOserId(String requestId, int i) {
		LambdaUpdateWrapper<Order> orderLambdaUpdateWrapper = new LambdaUpdateWrapper<>();
		orderLambdaUpdateWrapper.set(Order::getStatus,i).eq(Order::getOrderSn,requestId);
		this.update(orderLambdaUpdateWrapper);
	}

	@Override
	public Order findOrderByOrderId(String orderSn) {
		LambdaQueryWrapper<Order> orderLambdaQueryWrapper = new LambdaQueryWrapper<>();
		orderLambdaQueryWrapper.eq(Order::getOrderSn,orderSn);
		return this.getOne(orderLambdaQueryWrapper);
	}


	@Override
	public boolean checkNoPay(Long userId){
		long count = count(Wrappers.<Order>lambdaQuery().eq(Order::getMemberId, userId).eq(Order::getStatus, 0)
				.notIn(Order::getOrderType,4,5));
		return count > 0;
	}

}
